<template>
    <div class="page_root" :key="queryUpdateFlag" data-page-name="1" data-page-identification="k_0b41a5vodn">
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!-- begin vid_h5nz920zjb 自定义模板_8539sq95bk -->
            <a-modal
                v-model:visible="state.deleteMenuVisible"
                title="删除项目菜单"
                centered
                :keyboard="false"
                :mask-closable="false"
                @ok="handleDeleteMenu"
            >
                确定删除该项目吗？
            </a-modal>
            <!--          新建/编辑菜单-->
            <a-modal
                v-model:visible="state.menuVisible"
                :title="state.menuTitle"
                centered
                width="550px"
                :keyboard="false"
                :mask-closable="false"
                destroy-on-close
                @ok="handleSubmitMenu"
                @cancel="handleCancelMenu"
                :ok-button-props="{ loading: state.menuLoading }"
            >
                <a-form :model="state.menuForm" ref="menuRef">
                    <div class="menu-div">
                        <a-row>
                            <a-col :span="24">
                                <a-form-item
                                    label="菜单名称"
                                    :rules="[{ required: true, message: '请输入菜单名称', trigger: 'blur' }]"
                                    name="projectName"
                                >
                                    <a-input :placeholder="inputHolder" v-model:value="state.menuForm.projectName" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item
                                    label="父菜单"
                                    :rules="[{ required: true, message: '请选择父菜单', trigger: 'blur' }]"
                                    name="parentId"
                                >
                                    <a-tree-select
                                        show-search
                                        style="width: 100%"
                                        placeholder="请选择"
                                        allow-clear
                                        treeDefaultExpandAll
                                        v-model:value="state.menuForm.parentId"
                                        :fieldNames="{
                                            children: 'children',
                                            label: 'projectName',
                                            value: 'projectId',
                                            key: 'projectId'
                                        }"
                                        :tree-data="tgNoSt.projectList"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </div>
                </a-form>
            </a-modal>
            <!--          新建/编辑菜单-->
            <!--          选择产品类型-->
            <a-modal
                v-model:visible="state.selectProjectTypeVisible"
                title="新建"
                centered
                width="350px"
                :keyboard="false"
                :mask-closable="false"
                @ok="handleConfirmSelectType"
            >
                <a-radio-group v-model:value="state.selectProjectTypeRadioValue">
                    <a-radio value="模板项目">模板项目</a-radio>
                    <a-radio value="通用项目">通用项目</a-radio>
                    <a-radio value="项目菜单">项目菜单</a-radio>
                </a-radio-group>
            </a-modal>
            <!--          选择产品类型-->
            <!--          删除项目-->
            <a-modal
                v-model:visible="state.deleteVisible"
                centered
                :ok-button-props="{ loading: state.deleteLoading }"
                :mask-closable="false"
                :keyboard="false"
                @ok="handleSubmitDelete"
            >
                是否确认删除项目？
            </a-modal>
            <!--          删除项目-->
            <!--          转售后-->
            <a-modal
                v-model:visible="state.afterSalesVisible"
                centered
                :ok-button-props="{ loading: state.afterSalesLoading }"
                :mask-closable="false"
                :keyboard="false"
                @ok="handleSubmitAfterSales"
                @cancel="cancelAfter"
            >
                是否确认修改项目的转售后状态?？
            </a-modal>
            <!--          转售后-->
            <!--          新建模板项目-->
            <a-modal
                :title="tgNoSt.title"
                :visible="tgNoSt.visible"
                @ok="submitTgNoProject"
                width="1000px"
                :body-style="{ maxHeight: '700px', overflowY: 'auto' }"
                @cancel="tgNoStCancel"
                ok-text="提交"
                :maskClosable="false"
                destroy-on-close
                :ok-button-props="{ loading: tgNoSt.okDisibled }"
            >
                <a-form :model="tgNoSt.form" ref="tgNoStRef">
                    <div class="tg-no-st">
                        <div class="pj-title">
                            <div class="pj-title-son">基本信息</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目模板"
                                    name="projectTemplate"
                                    :rules="[{ required: true, message: '请选择项目模板', trigger: 'blur' }]"
                                >
                                    <a-select
                                        :disabled="tgNoSt.isEdit"
                                        :options="tgNoSt.projectTemplateList"
                                        :field-names="{ label: 'templateName', value: 'templateCode' }"
                                        @focus="getTemplate"
                                        @change="changeTemplate"
                                        :filter-option="
                                            (input, option) => {
                                                return (
                                                    option.templateName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                )
                                            }
                                        "
                                        v-model:value="tgNoSt.form.projectTemplate"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="工厂名称" name="factoryName" :rules="factoryRule.factory">
                                    <a-tree-select
                                        :options="tgNoSt.factoryNameList"
                                        :allowClear="true"
                                        :showSearch="true"
                                        :placeholder="'请选择'"
                                        tree-node-filter-prop="areaName"
                                        :fieldNames="{
                                            children: 'children',
                                            label: 'areaName',
                                            value: 'areaCode',
                                            key: 'areaCode'
                                        }"
                                        @focus="getFactory"
                                        :treeData="tgNoSt.factoryNameList"
                                        v-model:value="tgNoSt.form.factoryName"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item
                                    label="项目名称"
                                    name="projectName"
                                    :rules="{ required: true, message: '请输入项目名称', trigger: 'blur' }"
                                >
                                    <a-input
                                        v-model:value="tgNoSt.form.projectName"
                                        maxlength="50"
                                        show-count
                                        :placeholder="inputHolder"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目关联菜单"
                                    name="parentId"
                                    :rules="{ required: true, message: '请选择项目关联菜单', trigger: 'blur' }"
                                >
                                    <a-tree-select
                                        :fieldNames="{
                                            children: 'children',
                                            label: 'projectName',
                                            value: 'projectId',
                                            key: 'projectId'
                                        }"
                                        :showSearch="true"
                                        :placeholder="'请输入或选择'"
                                        :allowClear="true"
                                        :treeData="tgNoSt.projectList"
                                        v-model:value="tgNoSt.form.parentId"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="项目优先级"
                                    name="projectPriority"
                                    :rules="{ required: true, message: '请选择项目优先级', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="[
                                            { label: '最高', value: '最高' },
                                            { label: '高', value: '高' },
                                            { label: '中', value: '中' },
                                            { label: '低', value: '低' },
                                            { label: '最低', value: '最低' }
                                        ]"
                                        :showSearch="true"
                                        :placeholder="'请输入或选择'"
                                        :allowClear="true"
                                        v-model:value="tgNoSt.form.projectPriority"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="项目开始时间" name="startTime" :rules="factoryRule.startTime">
                                    <a-date-picker
                                        :disabled="tgNoSt.isEdit"
                                        v-model:value="tgNoSt.form.startTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择项目开始时间'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="启动会开始时间"
                                    name="kickoffMeetingStartDate"
                                    :rules="factoryRule.qdTime"
                                >
                                    <a-date-picker
                                        v-model:value="tgNoSt.form.kickoffMeetingStartDate"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择启动会开始时间'"
                                        style="width: 100%"
                                        :disabled="tgNoSt.isEdit && kickoffMeetingStartDateCheck"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="计划初验时间" name="deliveryTime" :rules="factoryRule.firstTime">
                                    <a-date-picker
                                        v-model:value="tgNoSt.form.deliveryTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择计划初验时间'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="计划终验时间" name="endTime" :rules="factoryRule.endTime">
                                    <a-date-picker
                                        v-model:value="tgNoSt.form.endTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择计划终验时间'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">项目领导小组</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="副总裁"
                                    name="vicePresident"
                                    :rules="{ required: true, message: '请选择副总裁', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tgNoSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tgNoSt.form.vicePresident"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">项目组负责人</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目总监"
                                    name="projectDirectorList"
                                    :rules="{ required: true, message: '请选择项目总监', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tgNoSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        mode="multiple"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tgNoSt.form.projectDirectorList"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="PMO"
                                    name="projectManagementOfficeList"
                                    :rules="{ required: true, message: '请选择PMO', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tgNoSt.peopleList"
                                        :allowClear="true"
                                        mode="multiple"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tgNoSt.form.projectManagementOfficeList"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目经理"
                                    name="pmNameList"
                                    :rules="{ required: true, message: '请选择项目经理', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tgNoSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        mode="multiple"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tgNoSt.form.pmNameList"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="客户满意中心负责人"
                                    name="afterSalesManagerList"
                                    :rules="{ required: true, message: '请选择客户满意中心负责人', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tgNoSt.peopleList"
                                        :allowClear="true"
                                        mode="multiple"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tgNoSt.form.afterSalesManagerList"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">项目组核心成员</div>
                        </div>
                        <a-row>
                            <a-col :span="12" v-for="(item, index) in tgNoSt.form.projectExtendsRoleList" :key="index">
                                <a-form-item
                                    :label="item.role"
                                    :name="['projectExtendsRoleList', index, 'userList']"
                                    :rules="{
                                        required: true,
                                        message: `请选择${item.role}`,
                                        trigger: 'blur'
                                    }"
                                >
                                    <a-select
                                        :options="tgNoSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        mode="multiple"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tgNoSt.form.projectExtendsRoleList[index].userList"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </div>

                    <div class="pj-title">
                        <div class="pj-title-son">甲方信息</div>
                    </div>
                    <!--                <a-form :model="tgNoSt.form.ppmProjectFirstPartyFormList">-->
                    <div
                        v-for="(item, index) in tgNoSt.form.ppmProjectFirstPartyFormList"
                        :key="index"
                        class="form-item"
                    >
                        <div class="role-content">
                            <a-row :gutter="24">
                                <a-col :span="8">
                                    <a-form-item label="角色">
                                        <a-input v-model:value="tgNoSt.form.ppmProjectFirstPartyFormList[index].role" />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="8">
                                    <a-form-item label="甲方名称">
                                        <a-input
                                            v-model:value="
                                                tgNoSt.form.ppmProjectFirstPartyFormList[index].firstPartyName
                                            "
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="8">
                                    <a-form-item label="联系方式">
                                        <a-input
                                            v-model:value="
                                                tgNoSt.form.ppmProjectFirstPartyFormList[index].contactInformation
                                            "
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </div>
                        <a class="del" @click="handlerDeletePartyItem(index)">删除</a>
                    </div>
                    <a-button type="primary" ghost class="add-btn-role" @click="handlerAddPartyItem">
                        <plus-outlined />
                        添加
                    </a-button>
                    <!--                </a-form>-->
                    <div class="pj-title">
                        <div class="pj-title-son">附件</div>
                        <a-button type="primary" size="small" @click="downJfFile">下载模板</a-button>
                    </div>
                    <div style="margin-bottom: 16px">
                        <a-row :gutter="24">
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tgNoSt.form.ppmEnclosureInfoList"
                                    :before-upload="handlerUploadTgNoA"
                                    @remove="handleRemoveTgNoSow"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        添加sow
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tgNoSt.form.commercialEnclosureInfoList"
                                    :before-upload="handlerUploadTgNoB"
                                    @remove="handleRemoveTgNoSW"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        添加商务合同
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tgNoSt.form.budgetEnclosureInfoList"
                                    :before-upload="handlerUploadTgNoC"
                                    @remove="handleRemoveTgNoYs"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        添加预算表
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tgNoSt.form.projectInfoList"
                                    :before-upload="handlerUploadTgXmxx"
                                    @remove="handleRemoveTgNoXmxx"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        项目信息收集表
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tgNoSt.form.industrialControlBrainList"
                                    :before-upload="handlerUploadTgGkzn"
                                    @remove="handleRemoveTgNoGkzn"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        工控智脑部署信息搜集表
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                        </a-row>
                    </div>
                    <div class="pj-title">
                        <div class="pj-title-son">预算信息</div>
                    </div>
                    <div>
                        <div class="ys-content">
                            <a-row :gutter="24">
                                <a-col :span="12">
                                    <a-form-item label="项目总预算">
                                        <a-input v-model:value="tgNoSt.form.budget" />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="12">
                                    <a-form-item label="人力成本预算">
                                        <a-input v-model:value="tgNoSt.form.humanCostBudget" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                            <a-row :gutter="24">
                                <a-col :span="12">
                                    <a-form-item label="直接费用预算">
                                        <a-input v-model:value="tgNoSt.form.directExpenseBudget" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                            <div class="pj-title">
                                <div class="pj-title-son no-border"></div>
                            </div>
                            <a-row :gutter="24">
                                <a-col :span="24">
                                    <a-form-item label="备注">
                                        <a-input v-model:value="tgNoSt.form.description" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                            <a-row :gutter="24" v-if="tgNoSt.isEdit">
                                <a-col :span="24">
                                    <a-form-item
                                        label="变更原因"
                                        name="reasonsChange"
                                        :rules="[{ required: true, message: '请输入变更原因', trigger: 'blur' }]"
                                    >
                                        <a-input v-model:value="tgNoSt.form.reasonsChange" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </div>
                    </div>
                </a-form>
            </a-modal>
            <!--          新建模板项目-->
            <!--          新建通用项目-->
            <a-modal
                :title="tyPjSt.title"
                :visible="tyPjSt.visible"
                @ok="submitTyProject"
                width="1000px"
                :body-style="{ maxHeight: '700px', overflowY: 'auto' }"
                @cancel="tyPjStCancel"
                ok-text="提交"
                :maskClosable="false"
                destroy-on-close
                :ok-button-props="{ loading: tyPjSt.okDisibled }"
            >
                <a-form :model="tyPjSt.form" ref="tyPjStRef">
                    <div class="tg-no-st">
                        <div class="pj-title">
                            <div class="pj-title-son">基本信息</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目名称"
                                    name="projectName"
                                    :rules="{ required: true, message: '请输入工厂名称', trigger: 'blur' }"
                                >
                                    <a-input
                                        v-model:value="tyPjSt.form.projectName"
                                        maxlength="50"
                                        show-count
                                        :placeholder="inputHolder"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="项目代号" name="projectCode">
                                    <a-input v-model:value="tyPjSt.form.projectCode" :placeholder="inputHolder" />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目关联菜单"
                                    name="parentId"
                                    :rules="{ required: true, message: '请选择项目关联菜单', trigger: 'blur' }"
                                >
                                    <a-tree-select
                                        :fieldNames="{
                                            children: 'children',
                                            label: 'projectName',
                                            value: 'projectId',
                                            key: 'projectId'
                                        }"
                                        :showSearch="true"
                                        :placeholder="'请输入或选择'"
                                        :allowClear="true"
                                        :treeData="tyPjSt.projectList"
                                        v-model:value="tyPjSt.form.parentId"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="项目优先级"
                                    name="projectPriority"
                                    :rules="{ required: true, message: '请选择项目优先级', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="[
                                            { label: '最高', value: '最高' },
                                            { label: '高', value: '高' },
                                            { label: '中', value: '中' },
                                            { label: '低', value: '低' },
                                            { label: '最低', value: '最低' }
                                        ]"
                                        :showSearch="true"
                                        :placeholder="'请输入或选择'"
                                        :allowClear="true"
                                        v-model:value="tyPjSt.form.projectPriority"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="合同实际签订时间">
                                    <a-date-picker
                                        v-model:value="tyPjSt.form.contractDate"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="合同计划开始时间" name="startTime" :rules="tyRule.startTime">
                                    <a-date-picker
                                        v-model:value="tyPjSt.form.startTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择'"
                                        style="width: 100%"
                                        :disabled="tyPjSt.isEdit && kickoffMeetingStartDateCheck"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="合同计划上线时间" name="deliveryTime" :rules="tyRule.deliveryTime">
                                    <a-date-picker
                                        v-model:value="tyPjSt.form.deliveryTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="合同计划完成时间" name="endTime" :rules="tyRule.endTime">
                                    <a-date-picker
                                        v-model:value="tyPjSt.form.endTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="合同实际完成时间">
                                    <a-date-picker
                                        v-model:value="tyPjSt.form.actualEndTime"
                                        :valueFormat="'YYYY-MM-DD'"
                                        :placeholder="'请选择'"
                                        style="width: 100%"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">项目领导小组</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="副总裁"
                                    name="vicePresident"
                                    :rules="{ required: true, message: '请选择副总裁', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.vicePresident"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">项目负责人</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目总监"
                                    name="projectDirector"
                                    :rules="{ required: true, message: '请选择项目总监', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.projectDirector"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="PMO"
                                    name="projectManagementOffice"
                                    :rules="{ required: true, message: '请选择PMO', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :placeholder="selectHolder"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.projectManagementOffice"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item
                                    label="项目经理"
                                    name="pmName"
                                    :rules="{ required: true, message: '请选择项目经理', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.pmName"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="客户满意中心负责人"
                                    name="afterSalesManager"
                                    :rules="{ required: true, message: '请选择客户满意中心负责人', trigger: 'blur' }"
                                >
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :placeholder="selectHolder"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.afterSalesManager"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div class="pj-title">
                            <div class="pj-title-son">项目组核心成员</div>
                        </div>
                        <a-row :gutter="24">
                            <a-col :span="12">
                                <a-form-item label="商务经理">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.preSaleManager"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="数据实施总监">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.dataImplementationDirector"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="数据治理工程师">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.dataGovernanceEngineer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="算法专家">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.algorithmExpert"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="交付经理">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.deliveryManager"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="产品经理">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.productLeaderName"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="技术经理">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.developLeaderName"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="测试经理">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.testLeaderName"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="客户满意工程师">
                                    <a-select
                                        :options="tyPjSt.peopleList"
                                        :allowClear="true"
                                        :dropdownMatchSelectWidth="true"
                                        :showSearch="true"
                                        :placeholder="selectHolder"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :fieldNames="{
                                            label: 'name',
                                            value: 'name'
                                        }"
                                        :showArrow="true"
                                        v-model:value="tyPjSt.form.afterSales"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </div>

                    <div class="pj-title">
                        <div class="pj-title-son">甲方信息</div>
                    </div>
                    <!--                <a-form :model="tyPjSt.form.ppmProjectFirstPartyFormList">-->
                    <div
                        v-for="(item, index) in tyPjSt.form.ppmProjectFirstPartyFormList"
                        :key="index"
                        class="form-item"
                    >
                        <div class="role-content">
                            <a-row :gutter="24">
                                <a-col :span="8">
                                    <a-form-item label="角色">
                                        <a-input v-model:value="tyPjSt.form.ppmProjectFirstPartyFormList[index].role" />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="8">
                                    <a-form-item label="甲方名称">
                                        <a-input
                                            v-model:value="
                                                tyPjSt.form.ppmProjectFirstPartyFormList[index].firstPartyName
                                            "
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="8">
                                    <a-form-item label="联系方式">
                                        <a-input
                                            v-model:value="
                                                tyPjSt.form.ppmProjectFirstPartyFormList[index].contactInformation
                                            "
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </div>
                        <a class="del" @click="handlerDeleteTyPartyItem(index)">删除</a>
                    </div>
                    <a-button type="primary" ghost class="add-btn-role" @click="handlerAddTyPartyItem">
                        <plus-outlined />
                        添加
                    </a-button>
                    <!--                </a-form>-->
                    <div style="margin-bottom: 16px">
                        <a-row :gutter="24">
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tyPjSt.form.ppmEnclosureInfoList"
                                    :before-upload="handlerUploadTyNoA"
                                    @remove="handleRemoveTgNoTySow"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        添加sow
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tyPjSt.form.commercialEnclosureInfoList"
                                    :before-upload="handlerUploadTyNoB"
                                    @remove="handleRemoveTyNoSw"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        添加商务合同
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                            <a-col :span="8">
                                <a-upload
                                    :file-list="tyPjSt.form.budgetEnclosureInfoList"
                                    :before-upload="handlerUploadTyNoC"
                                    @remove="handleRemoveTyNoYs"
                                    accept=".xlsx,.ppt,.pdf,.PDF, image/*, .docx, .rp, .xls"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        添加预算表
                                    </a-button>
                                </a-upload>
                                <span>支持格式：image/*,.xlsx,.xls,.docx,.rp,.ppt,.pptx,.pdf</span>
                            </a-col>
                        </a-row>
                    </div>
                    <div class="pj-title">
                        <div class="pj-title-son">预算信息</div>
                    </div>
                    <div>
                        <div class="ys-content">
                            <a-row :gutter="24">
                                <a-col :span="12">
                                    <a-form-item label="项目总预算">
                                        <a-input v-model:value="tyPjSt.form.budget" />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="12">
                                    <a-form-item label="人力成本预算">
                                        <a-input v-model:value="tyPjSt.form.humanCostBudget" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                            <a-row :gutter="24">
                                <a-col :span="12">
                                    <a-form-item label="直接费用预算">
                                        <a-input v-model:value="tyPjSt.form.directExpenseBudget" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                            <div class="pj-title">
                                <div class="pj-title-son no-border"></div>
                            </div>
                            <a-row :gutter="24">
                                <a-col :span="24">
                                    <a-form-item label="备注">
                                        <a-input v-model:value="tyPjSt.form.description" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                            <a-row :gutter="24" v-if="tyPjSt.isEdit">
                                <a-col :span="24">
                                    <a-form-item
                                        label="变更原因"
                                        name="reasonsChange"
                                        :rules="[{ required: true, message: '请输入变更原因', trigger: 'blur' }]"
                                    >
                                        <a-input v-model:value="tyPjSt.form.reasonsChange" />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </div>
                    </div>
                </a-form>
            </a-modal>
            <!--          新建通用项目-->
            <!-- begin vid_4yjzv1uwp4 自定义模板_he486ofo0e -->
            <div class="body">
                <div class="left-tree">
                    <div class="tree-title">
                        <div class="tree-title-font">交付项目列表</div>
                        <div style="display: flex; justify-content: end; align-items: center; gap: 8px">
                            <div
                                v-permission="'50001247_vid_dce58oobl1'"
                                class="export-all-icon"
                                title="导出模板项目附件"
                                @click="handleExportAllFile"
                                v-if="!loadingAll"
                            ></div>
                            <LoadingOutlined style="width: 16px; height: 16px; color: #3875ff" v-else />
                            <a-dropdown>
                                <div
                                    v-permission="'50001247_vid_9j2j4zwox1'"
                                    class="export-project-icon"
                                    title="导出"
                                ></div>
                                <template #overlay>
                                    <a-menu>
                                        <a-menu-item>
                                            <a href="javascript:;" @click="handlerProjectExport('全品明细模板')"
                                                >全品明细模板</a
                                            >
                                        </a-menu-item>
                                        <a-menu-item>
                                            <a href="javascript:;" @click="handlerProjectExport('全品阶段模板')"
                                                >全品阶段模板</a
                                            >
                                        </a-menu-item>
                                        <a-menu-item>
                                            <a href="javascript:;" @click="handlerProjectExport('任务状态模板')"
                                                >任务状态模板</a
                                            >
                                        </a-menu-item>
                                    </a-menu>
                                </template>
                            </a-dropdown>
                            <a-upload
                                v-permission="'50001247_vid_8pkm02ahgg'"
                                :multiple="true"
                                :before-upload="handlerUploadDetail"
                                @remove="handlerRemoveDetail"
                                :show-upload-list="false"
                                accept=".xlsx, image/*,.docx,, .xls,.mp4"
                            >
                                <div v-permission="'50001247_vid_8pkm02ahgg'" class="jf-import-icon" title="导入"></div>
                            </a-upload>
                            <div
                                class="new-add-icon"
                                v-permission="'50001247_vid_xvozjnibm4'"
                                title="新建"
                                @click="handleShowSelectProjectType"
                            ></div>
                        </div>
                    </div>
                    <div class="tree-search-div">
                        <a-input
                            v-model:value="state.treeSearchName"
                            placeholder="请输入"
                            allow-clear
                            @change="debounceGetProjectTreeData"
                        >
                            <template #suffix>
                                <a-tooltip title="">
                                    <search-outlined />
                                </a-tooltip>
                            </template>
                        </a-input>
                    </div>
                    <div class="tree-div">
                        <a-tree
                            v-model:checkedKeys="state.treeProps.checkedKeys"
                            v-model:selectedKeys="state.treeProps.selectedKeys"
                            v-model:expandedKeys="state.treeProps.expandedKeys"
                            :fieldNames="{
                                children: 'children',
                                title: 'projectName',
                                key: 'projectId'
                            }"
                            :selectedBackgroundColor="'#EBF1FF'"
                            :backgroundColor="'#F5F5F5'"
                            :show-line="true"
                            :show-icon="true"
                            :tree-data="state.projectTreeDate"
                            @select="handleTreeSelect"
                        >
                            <template #title="{ projectName, projectId, parentId, nodeType }" class="btn-show">
                                <div class="tree-btns">
                                    <span>{{ (projectId, projectName) }}</span>
                                    <a-dropdown v-if="nodeType === 'MENU'">
                                        <a class="ant-dropdown-link" @click.prevent style="margin-left: 8px">
                                            <MoreOutlined style="color: #3875ff" />
                                        </a>
                                        <template #overlay>
                                            <a-menu>
                                                <a-menu-item v-permission="'50001247_vid_e3bqrtf3ae'">
                                                    <a-button
                                                        size="small"
                                                        type="link"
                                                        @click.stop="
                                                            handleShowEditMenu(projectName, projectId, parentId)
                                                        "
                                                        >编辑</a-button
                                                    >
                                                </a-menu-item>
                                                <a-menu-item v-permission="'50001247_vid_em92g6v30w'">
                                                    <a-button
                                                        size="small"
                                                        type="link"
                                                        @click="handleShowDeleteMenu(projectId)"
                                                        >删除</a-button
                                                    >
                                                </a-menu-item>
                                            </a-menu>
                                        </template>
                                    </a-dropdown>
                                    <!--                                    <div-->
                                    <!--                                        v-if="nodeType === 'MENU'"-->
                                    <!--                                        style="display: inline-block; margin: 0 5px"-->
                                    <!--                                        @click.stop="handleShowEditMenu(projectName, projectId, parentId)"-->
                                    <!--                                    >-->
                                    <!--                                        <a-tooltip>-->
                                    <!--                                            <template #title>编辑</template>-->
                                    <!--                                            <EditOutlined class="bj-icon svg-icon" />-->
                                    <!--                                        </a-tooltip>-->
                                    <!--                                    </div>-->
                                    <!--                                    <a-popconfirm @confirm="handleDeleteMenu(projectId)" title="确定删除吗？">-->
                                    <!--                                        <div style="display: inline-block" v-if="nodeType === 'MENU'">-->
                                    <!--                                            <a-tooltip>-->
                                    <!--                                                <template #title>删除</template>-->
                                    <!--                                                <DeleteOutlined class="sc-icon svg-icon" />-->
                                    <!--                                            </a-tooltip>-->
                                    <!--                                        </div>-->
                                    <!--                                    </a-popconfirm>-->
                                </div>
                            </template>
                        </a-tree>
                    </div>
                </div>
                <div class="right-content">
                    <a-tabs
                        v-model:activeKey="state.activeKey"
                        class="tab-box"
                        @change="state.tabRefreshCount++"
                        :destroyInactiveTabPane="true"
                    >
                        <a-tab-pane v-for="tab in jfTabs" :key="tab.key" :tab="tab.label">
                            <component
                                v-if="state.selected.nodeType === 'PROJECT'"
                                :ref="el => (tabRefs[tab.key] = el)"
                                :active-key="state.activeKey"
                                :refresh-count="state.tabRefreshCount"
                                :is="tab.component"
                                v-bind="tab.getProps(state.selected, state.selected.projectId)"
                                @getTreeData="handleGiveSelectKeys"
                                @copyProject="handleCopyProject"
                            />
                        </a-tab-pane>
                        <div class="tab-btn">
                            <a-space
                                :size="16"
                                v-if="state.selected.projectId && state.selected.nodeType === 'PROJECT'"
                            >
                                <div class="switch-div" v-permission="'50001247_vid_xru5men0lo'">
                                    项目开关：<a-switch
                                        v-model:checked="state.projectDetail.projectStatusOnOrOff"
                                        @change="handleSwitchProject"
                                /></div>
                                <div class="switch-div" v-permission="'50001247_vid_8ljzo7zz8r'">
                                    转售后：<a-switch
                                        v-model:checked="state.projectDetail.afterSalesStatus"
                                        @change="handleShowAfter"
                                /></div>
                                <a-button
                                    type="primary"
                                    size="small"
                                    @click="editTgNoProject"
                                    ghost
                                    v-permission="'50001247_vid_e3bqrtf3ae'"
                                    >编辑</a-button
                                >
                                <a-button
                                    type="primary"
                                    size="small"
                                    @click="handleShowDelete"
                                    ghost
                                    v-permission="'50001247_vid_em92g6v30w'"
                                    >删除</a-button
                                >
                            </a-space>
                        </div>
                    </a-tabs>
                </div>
            </div>
            <!-- end vid_h5nz920zjb 自定义模板_8539sq95bk -->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        },
        'treeProps': {
            type: [String, Object, Array, Boolean],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    const vid_schmo0cokj_props = reactive({
        lazyParams: undefined,
        selected: { 'option': [], 'value': [], 'title': [], 'singleValue': '', 'singleLabel': '' },
        clickNode: { 'nodeKey': '', 'nodeTitle': '', 'nodeParentKey': '' },
        checkedKeys: [],
        selectedKeys: [],
        expandedKeys: []
    })

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    const vid_schmo0cokj_options_raw = ref([
        {
            'title': 'Node1',
            'value': '0-0',
            'key': '0-0',
            'children': [
                { 'value': '0-0-1', 'key': '0-0-1', 'title': 'Child Node2' },
                { 'title': 'Child Node2', 'value': '0-0-2', 'key': '0-0-2' }
            ]
        },
        { 'title': 'Node2', 'value': '0-1', 'key': '0-1' }
    ])

    const vid_schmo0cokj_options = computed(() => {
        return () => vid_schmo0cokj_options_raw.value
    })

    // 图表组件 树形控件_pp5knopjgf 条件格式数据依赖
    const vid_schmo0cokj_chartConditionDependencyMap = ref({})
    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */
    const vid_schmo0cokj_style = computed(() => {
        return { '--background-hover': '#f5f5f5', '--background-select': '#ebf1ff' }
    })

    const vid_schmo0cokj_style_span = computed(() => {
        return { marginLeft: '2px', color: '#595959' }
    })
    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    // ✅ 自动跳转并选中 + 展开节点
    async function getJumpId() {
        const urlParams = new URLSearchParams(window.location.search)
        const jumpId = urlParams.get('id')?.trim()
        if (!jumpId) return

        const jumpKey = Number(jumpId)
        console.log('跳转目标节点：', jumpKey)

        // 找到目标节点
        const targetNode = findNodeByKey(state.projectTreeDate, jumpKey)
        // 🚫 如果没找到（可能因为无权限或项目被删除）
        if (!targetNode) {
            message.warning('当前用户无权访问该项目或项目已不存在')
            return
        }

        // 找到目标节点的所有父级 key
        const parentKeys = findParentKeys(state.projectTreeDate, jumpKey)

        // ✅ 更新展开与选中
        state.treeProps.expandedKeys = [...new Set([...state.treeProps.expandedKeys, ...parentKeys, jumpKey])]
        state.treeProps.selectedKeys = [jumpKey]

        // ✅ 模拟 @select 事件
        handleTreeSelect([jumpKey], { selectedNodes: [targetNode] })
    }

    // ✅ 查找指定 key 的节点
    function findNodeByKey(list, key) {
        for (const item of list) {
            if (item.projectId === key) return item
            if (item.children?.length) {
                const found = findNodeByKey(item.children, key)
                if (found) return found
            }
        }
        return null
    }

    // ✅ 递归查找指定节点的所有父级 key
    function findParentKeys(list, key, path = []) {
        for (const item of list) {
            if (item.projectId === key) return path
            if (item.children?.length) {
                const result = findParentKeys(item.children, key, [...path, item.projectId])
                if (result.length) return result
            }
        }
        return []
    }

    onMounted(() => {
        getProjectTreeList()
        state.activeKey = jfTabs[0].key
    })
    function checkRequired(value, msg = '必填项缺失') {
        if (value === undefined || value === null || value === '') {
            message.warning(msg) // 这里用 Antd 的 message，也可以改成 console.error 或 throw Error
            return false
        }
        return true
    }
    const inputHolder = '请输入'
    const selectHolder = '请选择'
    import { nextTick, watch } from 'vue'
    import * as echarts from 'echarts'
    //     工厂信息
    import FactoryMsg from './Page3000001001.vue'
    // 任务
    import Task from './Page3000001169.vue'
    // 项目阶段
    import Milepost from './Page3000001170.vue'
    //     文件管理
    import ProjectFile from './Page3000000879.vue'
    import Overview from './Page3000001209.vue'
    import Risk from './Page3000001210.vue'
    import Changelog from './Page3000001211.vue'
    const state = reactive({
        treeProps: {
            lazyParams: undefined,
            clickNode: { nodeTitle: '', nodeKey: '', nodeParentKey: '' },
            checkedKeys: [],
            selectedKeys: [],
            expandedKeys: [],
            treeData: []
        },
        treeSearchName: undefined,
        projectTreeDate: [],
        activeKey: '',
        deleteVisible: false,
        deleteLoading: false,
        afterSalesVisible: false,
        afterSalesLoading: false,
        tabRefreshCount: 0,

        projectSwitch: true,
        selected: {},
        selectProjectTypeVisible: false,
        selectProjectTypeRadioValue: '模板项目',
        projectDetail: {},
        menuVisible: false,
        menuTitle: undefined,
        menuLoading: false,
        menuForm: {
            projectName: undefined,
            parentId: undefined
        },
        deleteMenuVisible: false
    })
    const projectId = ref()
    //     获取项目树
    async function getProjectTreeList() {
        await post('/solution-ppm/api/v2/built-in-system-ppm/delivery_project/tree/projectList', {
            projectName: state.treeSearchName
        }).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return false
            }
            state.projectTreeDate = data.data
            return true
        })
        await nextTick() // ✅ 等树渲染完
        getJumpId()
    }
    // 页面里直接手写防抖
    function debounce(fn, delay = 500) {
        let timer = null
        const debounced = function (...args) {
            clearTimeout(timer)
            timer = setTimeout(() => {
                fn.apply(this, args)
            }, delay)
        }
        debounced.cancel = () => {
            clearTimeout(timer)
            timer = null
        }
        return debounced
    }
    const debounceGetProjectTreeData = debounce(() => {
        getProjectTreeList()
    }, 500)
    let handleTreeSelect = throttle(async (keys, e) => {
        const node = e?.selectedNodes?.[0]

        console.log(node)
        if (node?.nodeType === 'MENU' || !node) {
            return
        }
        state.selected = node
        state.selected.projectId = keys[0]
        projectId.value = state.selected.projectId
        getData()
    }, 500)
    const getData = async (additionParams = {}) => {
        const url = `/solution-ppm/api/v2/built-in-system-ppm/delivery_project/${projectId.value}`
        return get(url)
            .then(async resp => {
                state.projectDetail = resp.data
                state.projectDetail.afterSalesStatus = state.projectDetail.afterSalesStatus === 'N' ? false : true
                return resp
            })
            .catch(async e => {
                return Promise.reject(e)
            })
            .finally(async () => {})
    }
    const jfTabs = [
        {
            key: 'overview',
            label: '项目概览',
            component: Overview,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        {
            key: 'milepost',
            label: '项目阶段',
            component: Milepost,
            getProps: (node, pid) => ({ projectId: pid, useProjectId: pid })
        },
        {
            key: 'task',
            label: '任务',
            component: Task,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        {
            key: 'risk',
            label: '风险',
            component: Risk,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        {
            key: 'changelog',
            label: '变更记录',
            component: Changelog,
            getProps: (node, pid) => ({ useProjectId: pid })
        },
        {
            key: 'ProjectFile',
            label: '项目文件管理',
            component: ProjectFile,
            getProps: (node, pid) => ({ useProjectId: pid, projectId: pid })
        },
        {
            key: 'FactoryMsg',
            label: '工厂信息',
            component: FactoryMsg,
            getProps: (node, pid) => ({ useProjectId: pid, projectId: pid })
        }
    ]
    // 导出
    function handlerProjectExport(type) {
        if (type === '全品明细模板') {
            get(`/solution-ppm/api/v2/built-in-system-ppm/delivery_task/exportAllVarietySpecialDetails`, null, {
                responseType: 'arraybuffer'
            }).then(res => {
                downloadExcel(res, `${type}.xlsx`)
            })
        } else {
            //可能会变
            get(
                `/solution-ppm/api/v2/built-in-system-ppm/v2/delivery_project_template/export_all_varieties_stage/${type}`,
                null,
                { responseType: 'arraybuffer' }
            ).then(res => {
                downloadExcel(res, `${type}.xlsx`)
            })
        }
    }
    // 新建选择类型
    function handleShowSelectProjectType() {
        state.selectProjectTypeVisible = true
        state.selectProjectTypeRadioValue = '模板项目'
    }
    //全部附件
    const loadingAll = ref(false)
    function handleExportAllFile() {
        if (!projectId.value) {
            message.info('请选择项目')
            return
        }
        loadingAll.value = true
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/v2/delivery_project_template/export_all_attachment/${projectId.value}`,
            null,
            { responseType: 'blob' }
        )
            .then(res => {
                if (res.type === 'application/octet-stream') {
                    downloadZip(res, '模板项目附件.zip')
                } else {
                    message.info(res.message || '没有附件')
                }
            })
            .finally(() => {
                loadingAll.value = false
            })
    }
    function removeNumberPrefix(text) {
        return text.replace(/^\d+(\.\d+)*\s*/gm, '')
    }
    // 父上传文件
    function handlerUploadDetail(file) {
        const data = new FormData()
        data.append('file', file)

        post(`/solution-ppm/api/v2/built-in-system-ppm/v2/delivery_project_template/role_user/excel_batch_import`, data)
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success(data.message)
                roleState.fileList = []
                dataConnector_conn_622s372c0e()
            })
            .catch(e => {
                message.error('上传失败' + e)
            })

        return false
    }

    // 父移除文件
    function handlerRemoveDetail(file) {
        roleState.fileList = roleState.fileList.filter(item => item.uid !== file.uid)
    }
    function handleConfirmSelectType() {
        if (state.selectProjectTypeRadioValue === '模板项目') {
            handleAddTemplateProject()
            state.selectProjectTypeRadioValue = '模板项目'
        } else if (state.selectProjectTypeRadioValue === '项目菜单') {
            handleAddMenu()
        } else {
            handleAddGeneralProject()
        }
    }
    function handleAddTemplateProject() {
        getPlist()
        getProjectList()
        tgNoSt.visible = true
        tgNoSt.title = '新建模板项目'
        tgNoSt.isEdit = false
        tgNoSt.isCopy = false
    }
    function handleAddGeneralProject() {
        getTyPlist()
        getTyProjectList()
        tyPjSt.visible = true
        tyPjSt.title = '新建交付项目'
        tyPjSt.isEdit = false
        tyPjSt.isCopy = false
    }
    // 模板项目=======================================================================================
    // tooltip样式
    const labelToolStyle = {
        maxWidth: '1000px'
    }
    const tgNoSt = reactive({
        visible: false,
        isEdit: false,
        title: '',
        okDisibled: false,
        form: {
            projectTemplate: undefined,
            factoryName: undefined,
            projectName: undefined,
            parentId: undefined,
            projectPriority: undefined,
            startTime: undefined,
            kickoffMeetingStartDate: undefined,
            afterSalesManager: undefined,
            deliveryTime: undefined,
            endTime: undefined,
            vicePresident: '叶丽文',
            projectDirector: undefined,
            projectManagementOffice: undefined,
            pmName: undefined,
            preSaleManager: undefined,
            productLeaderName: undefined,
            deliveryManager: undefined,
            developLeaderName: undefined,
            testLeaderName: undefined,
            ppmProjectFirstPartyFormList: [],
            ppmEnclosureInfoList: [],
            commercialEnclosureInfoList: [],
            budgetEnclosureInfoList: [],
            projectExtendsRoleList: [],
            projectInfoList: [],
            industrialControlBrainList: [],
            budget: undefined,
            humanCostBudget: undefined,
            directExpenseBudget: undefined,
            description: undefined,
            reasonsChange: undefined,
            projectType: '交付',
            projectId: projectId.value
        },

        projectTemplateList: [],
        //   工厂列表
        factoryNameList: [],
        //   项目关联菜单
        projectList: [],
        //   人列表
        peopleList: []
    })
    const ppmProjectFirstPartyItem = {
        role: undefined,
        firstPartyName: undefined,
        contactInformation: undefined
    }

    // 获取模板列表
    function getTemplate() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project/template/create/template_list/ONLINE').then(data => {
            if (data.code === 200) {
                tgNoSt.projectTemplateList = data.data.dataList
                tgNoSt.projectTemplateList.push({
                    templateId: '无模板',
                    templateName: '无模板',
                    templateCode: '无模板',
                    status: null,
                    delFlag: 0,
                    createdBy: null,
                    createdById: null,
                    createdTime: null,
                    modifiedBy: null,
                    modifiedById: null,
                    modifiedTime: null
                })
            } else {
                message.error('获取模板失败！')
            }
        })
    }

    //     获取工厂
    function getFactory() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project_template/ptf/search').then(data => {
            if (data.code === 200) {
                tgNoSt.factoryNameList = data.data
            } else {
                message.error('获取工厂名称失败！')
            }
        })
    }

    const factoryRule = {
        factory: [
            {
                required: true,
                trigger: 'blur',
                validator: async (rule, value, callback) => {
                    if (!value) {
                        return Promise.reject('请选择工厂名称')
                    }
                    const { data } = await post(
                        `/solution-ppm/api/v2/built-in-system-ppm/project_template/check_factory_valid/${value}`
                    )

                    return data ? Promise.resolve() : Promise.reject(new Error('请选择区域下的工厂'))
                }
            }
        ],
        startTime: [
            {
                required: true,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (!value) {
                        return Promise.reject('请输入项目开始时间')
                    }
                    if (
                        value &&
                        tgNoSt.form.endTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >=
                            dayjs(tgNoSt.form.endTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('项目开始不能晚于计划终验时间')
                    } else if (
                        value &&
                        tgNoSt.form.deliveryTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >=
                            dayjs(tgNoSt.form.deliveryTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('项目开始时间不能晚于计划初验时间')
                    } else if (
                        value &&
                        tgNoSt.form.kickoffMeetingStartDate &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >
                            dayjs(tgNoSt.form.kickoffMeetingStartDate).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('项目开始时间不能晚于启动会开始时间')
                    }
                    return Promise.resolve()
                }
            }
        ],
        qdTime: [
            {
                required: false,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (
                        value &&
                        tgNoSt.form.endTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >=
                            dayjs(tgNoSt.form.endTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('启动会开始时间不能晚于计划终验时间')
                    } else if (
                        value &&
                        tgNoSt.form.deliveryTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >=
                            dayjs(tgNoSt.form.deliveryTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('启动会开始时间不能晚于计划初验时间')
                    } else if (
                        value &&
                        tgNoSt.form.startTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <
                            dayjs(tgNoSt.form.startTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('启动会开始时间不能早于项目开始时间')
                    }
                    return Promise.resolve()
                }
            }
        ],
        firstTime: [
            {
                required: false,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (
                        value &&
                        tgNoSt.form.kickoffMeetingStartDate &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <=
                            dayjs(tgNoSt.form.kickoffMeetingStartDate).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划初验时间不能早于启动会开始时间')
                    } else if (
                        value &&
                        tgNoSt.form.endTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >=
                            dayjs(tgNoSt.form.endTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划初验时间不能晚于计划终验时间')
                    } else if (
                        value &&
                        tgNoSt.form.startTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <
                            dayjs(tgNoSt.form.startTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划初验时间不能早于项目开始时间')
                    }
                    return Promise.resolve()
                }
            }
        ],
        endTime: [
            {
                required: false,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    // 与预计上线时间对比
                    if (
                        value &&
                        tgNoSt.form.deliveryTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <=
                            dayjs(tgNoSt.form.deliveryTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划终验时间不能早于计划初验时间')
                    } else if (
                        value &&
                        tgNoSt.form.kickoffMeetingStartDate &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <=
                            dayjs(tgNoSt.form.kickoffMeetingStartDate).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划终验时间不能早于启动会开始时间')
                    } else if (
                        value &&
                        tgNoSt.form.startTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <
                            dayjs(tgNoSt.form.startTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('计划终验时间不能早于项目开始时间')
                    }
                    return Promise.resolve()
                }
            }
        ]
    }

    function getProjectList() {
        post('/solution-ppm/api/v2/built-in-system-ppm/delivery_project/tree/projectList', {
            source: 'MENU',
            nodeType: 'MENU'
        }).then(data => {
            if (data.code === 200) {
                tgNoSt.projectList = data.data
            } else {
                message.error('获取菜单失败！')
            }
        })
    }

    function getPlist() {
        get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/allUser').then(data => {
            if (data.code === 200) {
                tgNoSt.peopleList = data.data.userDtoList
            } else {
                message.error('获取用户列表失败！')
            }
        })
    }

    function handlerDeletePartyItem(index) {
        tgNoSt.form.ppmProjectFirstPartyFormList.splice(index, 1)
    }

    function handlerAddPartyItem() {
        tgNoSt.form.ppmProjectFirstPartyFormList.push({ ...ppmProjectFirstPartyItem })
    }

    function handlerUploadTgNoA(file) {
        const data = new FormData()
        data.append('file', file)
        post('/file-storage/api/v1/file/upload', data).then(({ data: { fullUrl } }) => {
            if (data) {
                tgNoSt.form.ppmEnclosureInfoList = [
                    ...tgNoSt.form.ppmEnclosureInfoList,
                    {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }
                ]
            }
        })
        return false
    }
    function handlerUploadTgNoB(file) {
        const data = new FormData()
        data.append('file', file)
        post('/file-storage/api/v1/file/upload', data).then(({ data: { fullUrl } }) => {
            if (data) {
                tgNoSt.form.commercialEnclosureInfoList = [
                    ...tgNoSt.form.commercialEnclosureInfoList,
                    {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }
                ]
            }
        })
        return false
    }

    function handlerUploadTgNoC(file) {
        const data = new FormData()
        data.append('file', file)
        post('/file-storage/api/v1/file/upload', data).then(({ data: { fullUrl } }) => {
            if (data) {
                tgNoSt.form.budgetEnclosureInfoList = [
                    ...tgNoSt.form.budgetEnclosureInfoList,
                    {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }
                ]
            }
        })
        return false
    }

    const tgNoStRef = ref(null)

    function submitTgNoProject() {
        tgNoStRef.value.validate().then(() => {
            tgNoSt.okDisibled = true
            const params = cloneDeep(tgNoSt.form)
            params.projectExtendsRoleList.forEach(item => {
                item.user = item.userList.join(',')
            })
            if (tgNoSt.isEdit) {
                //修改推广无模板项目
                if (tgNoSt.form.projectTemplate !== '无模板') {
                    post('/solution-ppm/api/v2/built-in-system-ppm/v2/delivery_project_template/edit', params)
                        .then(data => {
                            if (data.code === 200) {
                                message.success('编辑项目已进入审批流程')
                                tgNoSt.visible = false

                                resetTgPjForm()
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            tgNoSt.okDisibled = false
                        })
                } else {
                    //修改推广有模板项目
                    post('/solution-ppm/api/v2/built-in-system-ppm/v2/delivery_project_generalization/edit', params)
                        .then(data => {
                            if (data.code === 200) {
                                message.success('编辑项目已进入审批流程')
                                tgNoSt.visible = false

                                state.selectProjectTypeVisible = false
                                resetTgPjForm()
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            tgNoSt.okDisibled = false
                        })
                }
            } else {
                if (tgNoSt.form.projectTemplate !== '无模板') {
                    // 新增推广无模板项目
                    post('/solution-ppm/api/v2/built-in-system-ppm/v2/delivery_project_template/add', params)
                        .then(data => {
                            if (data.code === 200) {
                                message.success('新建项目已进入审批流程')
                                tgNoSt.visible = false
                                resetTgPjForm()
                                state.selectProjectTypeVisible = false
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            tgNoSt.okDisibled = false
                        })
                } else {
                    // 新增推广有模板项目
                    post('/solution-ppm/api/v2/built-in-system-ppm/v2/delivery_project_generalization/add', params)
                        .then(data => {
                            if (data.code === 200) {
                                message.success('新建项目已进入审批流程')
                                tgNoSt.visible = false

                                resetTgPjForm()
                            } else {
                                message.error(data.message)
                            }
                        })
                        .finally(() => {
                            tgNoSt.okDisibled = false
                        })
                }
            }
        })
    }
    function editTgNoProject() {
        if (state.selected.projectTemplate) {
            //   编辑模板
            // 使用 Promise.all() 等待所有异步方法完成
            Promise.all([getFactory(), getPlist(), getProjectList(), getTemplate()])
                .then(() => {
                    // 在所有方法都成功完成后执行最后一步
                    get(`/solution-ppm/api/v2/built-in-system-ppm/delivery_project/${projectId.value}`).then(
                        ({ data }) => {
                            tgNoSt.form = Object.assign({}, tgNoSt.form, data)
                            tgNoSt.form.ppmEnclosureInfoList = data.ppmEnclosureDtoList
                            tgNoSt.form.ppmProjectFirstPartyFormList = data.ppmProjectFirstPartyDtoList
                            if (!data.projectTemplate) {
                                tgNoSt.form.projectTemplate = '无模板'
                            }
                            tgNoSt.visible = true
                            tgNoSt.isEdit = true
                            tgNoSt.title = '编辑模板项目'
                        }
                    )
                })
                .catch(error => {
                    // 如果其中任何一个方法失败，处理错误
                    console.error('Error:', error)
                })
        } else {
            // 编辑非模板
            Promise.all([getTyPlist(), getTyProjectList()])
                .then(() => {
                    // 在所有方法都成功完成后执行最后一步
                    get(`/solution-ppm/api/v2/built-in-system-ppm/delivery_project/${projectId.value}`).then(
                        ({ data }) => {
                            tyPjSt.form = Object.assign({}, tyPjSt.form, data)
                            tyPjSt.form.ppmEnclosureInfoList = data.ppmEnclosureDtoList
                            tyPjSt.form.ppmProjectFirstPartyFormList = data.ppmProjectFirstPartyDtoList
                            tyPjSt.visible = true
                            tyPjSt.isEdit = true
                            tyPjSt.title = '编辑通用项目'
                        }
                    )
                })
                .catch(error => {
                    // 如果其中任何一个方法失败，处理错误
                    console.error('Error:', error)
                })
        }
    }

    function tgNoStCancel() {
        resetTgPjForm()
        tgNoSt.visible = false
    }

    function resetTgPjForm() {
        tgNoSt.form = {
            projectTemplate: undefined,
            factoryName: undefined,
            projectName: undefined,
            parentId: undefined,
            projectPriority: undefined,
            startTime: undefined,
            kickoffMeetingStartDate: undefined,
            deliveryTime: undefined,
            endTime: undefined,
            vicePresident: '叶丽文',
            projectDirector: undefined,
            projectManagementOffice: undefined,
            pmName: undefined,
            preSaleManager: undefined,
            productLeaderName: undefined,
            deliveryManager: undefined,
            developLeaderName: undefined,
            testLeaderName: undefined,
            ppmProjectFirstPartyFormList: [],
            ppmEnclosureInfoList: [],
            commercialEnclosureInfoList: [],
            budgetEnclosureInfoList: [],
            projectExtendsRoleList: [],
            projectInfoList: [],
            industrialControlBrainList: [],
            budget: undefined,
            humanCostBudget: undefined,
            directExpenseBudget: undefined,
            description: undefined,
            reasonsChange: undefined,
            projectType: '交付',
            projectId: projectId.value
        }
    }

    function changeTemplate(value) {
        if (value == '无模板') {
            tgNoSt.form.factoryName = undefined
        } else {
            get(
                `/solution-ppm/api/v2/built-in-system-ppm/v2/platform_project_template/project_extends_role/delivery/${tgNoSt.form.projectTemplate}`
            ).then(data => {
                tgNoSt.form.projectExtendsRoleList = data.data
            })
        }
    }

    function handleRemoveTgNoSow(file) {
        tgNoSt.form.ppmEnclosureInfoList = tgNoSt.form.ppmEnclosureInfoList.filter(item => item.uid !== file.uid)
    }

    function handleRemoveTgNoSw(file, type) {
        tgNoSt.form.commercialEnclosureInfoList = tgNoSt.form.commercialEnclosureInfoList.filter(
            item => item.uid !== file.uid
        )
    }

    function handleRemoveTgNoYs(file) {
        tgNoSt.form.budgetEnclosureInfoList = tgNoSt.form.budgetEnclosureInfoList.filter(item => item.uid !== file.uid)
    }

    function handleRemoveTgNoXmxx(file) {
        tgNoSt.form.projectInfoList = tgNoSt.form.projectInfoList.filter(item => item.uid !== file.uid)
    }

    function handleRemoveTgNoGkzn(file) {
        tgNoSt.form.industrialControlBrainList = tgNoSt.form.industrialControlBrainList.filter(
            item => item.uid !== file.uid
        )
    }
    // 模板项目=======================================================================================
    // 通用项目=======================================================================================

    const tyPjSt = reactive({
        visible: false,
        isEdit: false,
        title: '',
        okDisibled: false,
        form: {
            projectTemplate: undefined,
            factoryName: undefined,
            projectName: undefined,
            parentId: undefined,
            projectPriority: undefined,
            startTime: undefined,
            kickoffMeetingStartDate: undefined,
            afterSalesManager: undefined,
            deliveryTime: undefined,
            endTime: undefined,
            vicePresident: '叶丽文',
            projectDirector: undefined,
            projectManagementOffice: undefined,
            pmName: undefined,
            preSaleManager: undefined,
            productLeaderName: undefined,
            deliveryManager: undefined,
            developLeaderName: undefined,
            testLeaderName: undefined,
            ppmProjectFirstPartyFormList: [],
            ppmEnclosureInfoList: [],
            commercialEnclosureInfoList: [],
            budgetEnclosureInfoList: [],
            projectExtendsRoleList: [],
            projectInfoList: [],
            industrialControlBrainList: [],
            budget: undefined,
            humanCostBudget: undefined,
            directExpenseBudget: undefined,
            description: undefined,
            reasonsChange: undefined,
            projectType: '交付',
            projectId: projectId.value
        },

        projectTemplateList: [],
        //   工厂列表
        factoryNameList: [],
        //   项目关联菜单
        projectList: [],
        //   人列表
        peopleList: []
    })

    function getTyProjectList() {
        post('/solution-ppm/api/v2/built-in-system-ppm/delivery_project/tree/projectList', {
            source: 'MENU',
            nodeType: 'MENU'
        }).then(data => {
            if (data.code === 200) {
                tyPjSt.projectList = data.data
            } else {
                message.error('获取菜单失败！')
            }
        })
    }

    function getTyPlist() {
        get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/allUser').then(data => {
            if (data.code === 200) {
                tyPjSt.peopleList = data.data.userDtoList
            } else {
                message.error('获取用户列表失败！')
            }
        })
    }
    function handlerDeleteTyPartyItem(index) {
        tyPjSt.form.ppmProjectFirstPartyFormList.splice(index, 1)
    }

    function handlerAddTyPartyItem() {
        tyPjSt.form.ppmProjectFirstPartyFormList.push({ ...ppmProjectFirstPartyItem })
    }

    function handlerUploadTyNoA(file) {
        const data = new FormData()
        data.append('file', file)
        post('/file-storage/api/v1/file/upload', data).then(({ data: { fullUrl } }) => {
            if (data) {
                tyPjSt.form.ppmEnclosureInfoList = [
                    ...tyPjSt.form.ppmEnclosureInfoList,
                    {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }
                ]
            }
        })
        return false
    }
    function handlerUploadTyNoB(file) {
        const data = new FormData()
        data.append('file', file)
        post('/file-storage/api/v1/file/upload', data).then(({ data: { fullUrl } }) => {
            if (data) {
                tyPjSt.form.commercialEnclosureInfoList = [
                    ...tyPjSt.form.commercialEnclosureInfoList,
                    {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }
                ]
            }
        })
        return false
    }

    function handlerUploadTyNoC(file) {
        const data = new FormData()
        data.append('file', file)
        post('/file-storage/api/v1/file/upload', data).then(({ data: { fullUrl } }) => {
            if (data) {
                tyPjSt.form.budgetEnclosureInfoList = [
                    ...tyPjSt.form.budgetEnclosureInfoList,
                    {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }
                ]
            }
        })
        return false
    }

    const tyPjStRef = ref(null)

    function submitTyProject() {
        tyPjStRef.value.validate().then(() => {
            tyPjSt.okDisibled = true
            if (tyPjSt.isEdit) {
                delete tyPjSt.form.afterSalesStatus
                post('/solution-ppm/api/v2/built-in-system-ppm/delivery_project/approveEditProject', {
                    ...tyPjSt.form,
                    projectId: projectId.value
                })
                    .then(data => {
                        if (data.code !== 200) {
                            message.error(data.message)
                            return
                        }
                        message.success(data.message)
                        state.selectProjectTypeVisible = false
                        resetTyPjForm()
                        getProjectList()
                    })
                    .finally(() => {
                        tyPjSt.okDisibled = false
                    })
            } else {
                post('/solution-ppm/api/v2/built-in-system-ppm/delivery_project/add', tyPjSt.form)
                    .then(data => {
                        if (data.code !== 200) {
                            message.error(data.message)
                            return
                        }
                        message.success(data.message)
                        state.selectProjectTypeVisible = false
                        resetTyPjForm()
                        getProjectList()
                    })
                    .finally(() => {
                        tyPjSt.okDisibled = false
                    })
            }
        })
    }

    function tyPjStCancel() {
        resetTgPjForm()
        tyPjSt.visible = false
    }

    function resetTyPjForm() {
        tyPjSt.visible = false
        tyPjSt.form = {
            projectTemplate: undefined,
            factoryName: undefined,
            projectName: undefined,
            parentId: undefined,
            projectPriority: undefined,
            startTime: undefined,
            kickoffMeetingStartDate: undefined,
            deliveryTime: undefined,
            endTime: undefined,
            vicePresident: '叶丽文',
            projectDirector: undefined,
            projectManagementOffice: undefined,
            pmName: undefined,
            preSaleManager: undefined,
            productLeaderName: undefined,
            deliveryManager: undefined,
            developLeaderName: undefined,
            testLeaderName: undefined,
            ppmProjectFirstPartyFormList: [],
            ppmEnclosureInfoList: [],
            commercialEnclosureInfoList: [],
            budgetEnclosureInfoList: [],
            projectExtendsRoleList: [],
            projectInfoList: [],
            industrialControlBrainList: [],
            budget: undefined,
            humanCostBudget: undefined,
            directExpenseBudget: undefined,
            description: undefined,
            reasonsChange: undefined,
            projectType: '交付',
            projectId: projectId.value
        }
    }
    const tyRule = {
        startTime: [
            {
                required: true,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (!value) {
                        return Promise.reject('请输入项目开始时间')
                    }
                    if (
                        value &&
                        tyPjSt.form.endTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >
                            dayjs(tyPjSt.form.endTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('合同计划开始时间不能晚于合同计划完成时间')
                    } else if (
                        value &&
                        tyPjSt.form.deliveryTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >
                            dayjs(tyPjSt.form.deliveryTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('合同计划开始时间不能晚于合同计划上线时间')
                    }
                    return Promise.resolve()
                }
            }
        ],
        deliveryTime: [
            {
                required: false,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (
                        value &&
                        tyPjSt.form.endTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') >
                            dayjs(tyPjSt.form.endTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('合同计划上线时间不能晚于合同计划完成时间')
                    } else if (
                        value &&
                        tyPjSt.form.startTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <
                            dayjs(tyPjSt.form.startTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('合同计划上线时间不能早于合同计划开始时间')
                    }
                    return Promise.resolve()
                }
            }
        ],
        endTime: [
            {
                required: false,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                    if (
                        value &&
                        tyPjSt.form.deliveryTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <=
                            dayjs(tyPjSt.form.deliveryTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('合同计划完成时间不能早于合同计划上线时间')
                    } else if (
                        value &&
                        tyPjSt.form.startTime &&
                        dayjs(value).format('YYYY-MM-DD hh-mm-ss') <
                            dayjs(tyPjSt.form.startTime).format('YYYY-MM-DD hh-mm-ss')
                    ) {
                        return Promise.reject('合同计划完成时间不能早于合同计划开始时间')
                    }
                    return Promise.resolve()
                }
            }
        ]
    }

    function handleRemoveTgNoTySow(file) {
        tyPjSt.form.ppmEnclosureInfoList = tyPjSt.form.ppmEnclosureInfoList.filter(item => item.uid !== file.uid)
    }

    function handleRemoveTyNoSw(file) {
        tyPjSt.form.commercialEnclosureInfoList = tyPjSt.form.commercialEnclosureInfoList.filter(
            item => item.uid !== file.uid
        )
    }

    function handleRemoveTyNoYs(file) {
        tyPjSt.form.budgetEnclosureInfoList = tyPjSt.form.budgetEnclosureInfoList.filter(item => item.uid !== file.uid)
    }
    //     删除项目
    function handleShowDelete() {
        if (!checkRequired(state.selected.projectId, '请选择产品')) return
        state.deleteVisible = true
    }
    function handleSubmitDelete() {
        state.deleteLoading = true
        del(`/solution-ppm/api/v2/built-in-system-ppm/delivery_project/approveDeleteProject/${state.selected.projectId}`)
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success(data.message)
                getProjectTreeList()
                handleCancelMenu()
            })
            .finally(() => {
                state.deleteLoading = false
            })
    }

    function handleSwitchProject() {
        post('/solution-ppm/api/v2/built-in-system-ppm/delivery_project/updateProjectStatusOnOrOff', {
            projectId: projectId.value
        })
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success(data.message)
            })
            .finally(() => {
                getData()
            })
    }
    function handleShowAfter() {
        state.afterSalesVisible = true
    }
    function handleSubmitAfterSales() {
        state.afterSalesLoading = true
        put(`/solution-ppm/api/v2/built-in-system-ppm/delivery_project/after_sales_status`, {
            projectId: state.selected.projectId,
            afterSalesStatus: !!state.projectDetail.afterSalesStatus
        })
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                state.afterSalesVisible = false
                message.success(data.message)
            })
            .finally(() => {
                state.afterSalesLoading = false
                callChildMethod()
            })
    }
    const tabRefs = reactive({}) // 保存每个 tab 的子组件实例

    const callChildMethod = () => {
        const currentTab = state.activeKey
        const child = tabRefs[currentTab]
        if (child && child.getData) {
            child.getData()
        } else {
            console.warn('当前 Tab 未找到对应方法')
        }
    }
    function cancelAfter() {
        state.afterSalesVisible = false
        getData()
    }
    // 通用项目=======================================================================================
    //     项目菜单
    const menuRef = ref(null)
    function handleAddMenu() {
        state.menuVisible = true
        state.menuTitle = '新建项目菜单'
        getProjectList()
    }
    const currentMenu = ref({})
    function handleSubmitMenu() {
        menuRef.value.validate().then(() => {
            state.menuLoading = true
            const api = currentMenu.value.projectId ? put : post
            const url = currentMenu.value.projectId
                ? '/solution-ppm/api/v2/built-in-system-ppm/project/v2/edit/projectMenu'
                : '/solution-ppm/api/v2/built-in-system-ppm/project/v2/add/projectMenu'
            api(url, { ...state.menuForm, projectId: currentMenu.value.projectId })
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    handleCancelMenu()
                    state.menuLoading = false
                    state.selectProjectTypeVisible = false
                    getProjectTreeList()
                })
                .finally(() => {
                    state.menuLoading = false
                })
        })
    }
    function handleShowEditMenu(projectName, projectId, parentId) {
        getProjectList()
        currentMenu.value = { projectName, projectId, parentId }
        state.menuVisible = true
        state.menuForm.projectName = projectName
        state.menuForm.parentId = parentId
        state.menuTitle = '编辑项目菜单'
    }
    const deleteMenuId = ref()
    function handleShowDeleteMenu(id) {
        state.deleteMenuVisible = true
        deleteMenuId.value = id
    }
    function handleDeleteMenu(projectId) {
        del(`/solution-ppm/api/v2/built-in-system-ppm/project/v2/menu/${deleteMenuId.value}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            handleCancelMenu()
            getProjectTreeList()
        })
    }
    function handleCancelMenu() {
        state.menuVisible = false
        state.menuForm = {
            projectName: undefined,
            parentId: undefined
        }
    }
    //     项目菜单
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }
    .vid_schmo0cokj :deep(span) {
        color: undefined;
    }
    /*样式*/

    .body {
        display: flex;
        gap: 16px;
        height: 100%;
    }
    /*左侧树*/
    .left-tree {
        width: 16%;
        display: flex;
        flex-direction: column;
        background-color: #fff;
    }

    .svg-icon {
        display: block;
        position: relative;
        top: 0px;
        outline: none;
        color: #262626;
    }
    .tree-btns {
        display: flex;
        justify-content: space-around;
    }
    :deep(.ant3-tree-node-content-wrapper:hover) .svg-icon {
        display: inline-block;
        margin: 0;
    }
    .new-add-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/492790240417114112-source.png');
        background-size: cover;
        cursor: pointer;
        margin-bottom: 3px;
    }
    .tree-title {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 16px 24px 0;
    }
    .tree-title-font {
        font-weight: 600;
        color: #262626;
    }
    .tree-search-div {
        margin-top: 8px;
        margin-bottom: 16px;
        padding-right: 24px;
        padding-left: 24px;
    }
    .tree-div {
        flex: 1;
        padding: 0 24px;
        overflow-y: auto;
    }
    /*左侧树*/
    /*右侧内容*/
    .right-content {
        flex: 1;
        padding-right: 16px;
        padding-bottom: 16px;
        padding-left: 16px;
        background-color: #fff;
        overflow: hidden;
    }
    .tab-btn {
        position: absolute;
        right: 0;
        top: 12px;
    }
    .tab-box {
        position: relative;
    }
    /*右侧内容*/

    /*模板项目样式*/
    /*
        定制
        */
    .pj-title {
        height: 30px;
        border-bottom: 1px solid #bfbfbf;
        margin-bottom: 16px;
    }

    .pj-title-son {
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        border-left: 4px solid #3875ff;
        padding-left: 5px;
        height: 18px;
        line-height: 18px;
    }

    :deep(.tg-no-st .ant3-form-item-label) {
        width: 115px !important;
    }
    :deep(.menu-div .ant3-form-item-label) {
        width: 85px !important;
    }
    :deep(.iteration-form .ant3-form-item-label) {
        width: 85px !important;
    }

    .del {
        width: 66px;
        color: #3875ff;
        float: right;
    }

    .add-btn-role {
        margin-bottom: 20px;
    }

    .role-content {
        display: inline-block;
        width: calc(100% - 80px);
    }

    :deep(.role-content .ant3-form-item-label) {
        width: 115px !important;
    }

    .no-border {
        border: none;
    }
    .table-box :deep(.@{ant-prefix}-table-tbody) tr > td {
        font-size: 14px;
        font-weight: 400;
        color: #262626;
        border-bottom: 1px solid #d9d9d9;
        padding: 8px 16px;
        word-break: break-all;
    }
    /*模板项目样式*/
    .yjjdlx,
    .yjjd,
    .kfjdlx,
    .kfjd,
    .jxjd,
    .ssjd,
    .xyfp {
        width: 16px;
        height: 16px;
        background-size: cover;
        flex-shrink: 0;
    }
    .yjjdlx {
        background-image: url('http://10.40.0.33:9001/file-storage/531434247375108096-source.png');
    }
    .yjjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434220309264384-source.png');
    }
    .kfjdlx {
        background-image: url('http://10.40.0.33:9001/file-storage/531434101583198208-source.png');
    }
    .kfjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434061735213056-source.png');
    }
    .jxjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434030753986560-source.png');
    }
    .ssjd {
        background-image: url('http://10.40.0.33:9001/file-storage/531434149779945472-source.png');
    }
    .xyfp {
        background-image: url('http://10.40.0.33:9001/file-storage/531434188644366336-source.png');
    }
    .tree-name {
        display: flex;
        align-items: center;
        gap: 4px;
    }

    .stage-icon {
        width: 16px;
        height: 16px;
        background-size: cover;
    }

    /*
        定制
        */

    /*新需求*/
    .content-box .right-table .search {
        padding: 10px 24px;
        padding-top: 5px;
        background: #fff;
        margin-bottom: 16px;
        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
        border-radius: 4px;
    }
    .content-box .right-table .search-top {
        padding: 10px 24px;
        background: #fff;
        margin-bottom: 14px;
        border-bottom: 1px solid #d9d9d9;
    }
    .target-content {
        padding: 5px 10px;
        width: 100%;
        border: 1px solid #d9d9d9;
        border-radius: 2px;
        min-height: 34px;
        word-wrap: break-word; /* 强制换行 */
        overflow-wrap: break-word; /* 支持较旧浏览器 */
        white-space: pre-wrap; /* 保持换行符 */
        max-height: 35px;
        overflow: auto;
    }
    .target-title {
        font-size: 14px;
        color: #595959;
        letter-spacing: 0;
        font-weight: 400;
        margin: 5px 0;
    }

    .content-box .right-table {
        padding: 10px;
    }
    :deep(.ant3-tabs > .ant3-tabs-nav, .ant3-tabs > div > .ant3-tabs-nav) {
        margin-bottom: 8px;
    }
    .xmjd-main {
        margin-top: 12px;
    }

    .top-main-out {
        display: flex;
        gap: 16px;
    }
    .target-div {
        width: 50%;
    }
    /*新需求*/

    /*动态角色*/
    .pj-title {
        display: flex;
        justify-content: space-between;
    }
    :deep(.role-content .ant3-form-item-label) {
        width: 80px !important;
    }
    :deep(.ys-content .ant3-form-item-label) {
        width: 115px !important;
    }
    .role-item {
        display: flex;
    }
    .role-label {
        color: #595959;
    }
    .role-value {
        color: #3875ff;
        font-weight: 600;
    }
    .role-content-detail {
        min-width: 100%;
    }
    /*动态角色*/

    .export-project-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/493521074667350016-source.png');
        background-size: cover;
        cursor: pointer;
    }
    .vid_3ef6izs1om {
        align-items: unset;
    }

    /*导出全部*/
    .export-all-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/500954764278196224-source.png');
        background-size: cover;
        cursor: pointer;
    }
    /*导出全部*/
    :deep(.tg-no-st .ant3-form-item-label) {
        width: 155px !important;
    }

    .vid_t2atpckh13,
    .vid_21d4lhn6ae {
        background-image: linear-gradient(to bottom, #f2f6fc, #fff);
        border-left-style: none;
    }
    .vid_9h9c2le2ct {
        background-image: linear-gradient(to bottom, #f2f6fc, #fff);
        border-left-color: #fff;
    }
    //超出省略
    .vid_2ma9mye8nl {
        width: 96%;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        color: #333;
        font-size: 16px;
    }
    /*树样式*/
    .vid_wzwralami7 {
        height: calc(100vh - 220px);
    }
    .vid_psnwdjh4xe {
        max-height: unset;
        height: calc(100vh - 210px);
    }
    .jf-import-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/527620686083340288.png');
        background-size: cover;
        cursor: pointer;
        position: relative;
        bottom: -3px;
    }
    .new-add-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/527620685374502912.png');
        background-size: cover;
        cursor: pointer;
        margin-bottom: 3px;
    }
    .role-content-detail {
        max-height: 80px;
        overflow-y: auto; /* 超出显示滚动条 */
    }

    .role-item {
        display: flex;
        align-items: center;
        margin-bottom: 8px;
    }

    .role-label {
        flex: 0 0 auto; /* label 不被压缩 */
        margin-right: 4px;
        white-space: nowrap; /* 不换行 */
    }

    .role-value {
        flex: 1 1 auto; /* value 占满剩余空间 */
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap; /* 超出用 ... */
    }
    .switch-div {
        display: flex;
        align-items: center;
    }
    /*覆盖样式*/
    .tree-btns {
        display: flex;
        justify-content: space-around;
    }
    :deep(.ant3-tree-node-content-wrapper:hover) .svg-icon {
        display: inline-block;
        margin-left: 5px;
    }
    .bj-icon,
    .fb-icon,
    .xx-icon,
    .sc-icon {
        width: 16px;
        height: 16px;
        background-size: cover;
    }

    .fb-icon {
        background-image: url('http://10.40.0.33:9001/file-storage/498072051854567424-source.png');
    }
    .xx-icon {
        background-image: url('http://10.40.0.33:9001/file-storage/498071804598249472-source.png');
    }
</style>
